﻿using LiveChartsCore;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using PLC.Interface.ActualDatas;
using PLC.Interface.Stations;
using PLCWpfTest.Common;
using PLCWpfTest.Common.Extensions;
using PLCWpfTest.Models;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;

namespace PLCWpfTest.ViewModels
{
    public class CentralMonitoringViewModel : BaseViewModel, IDisposable
    {
        /// <summary>
        /// 计时器
        /// </summary>
        private readonly Timer _timer;

        private IReadOnlyList<StationResultDto> _stations;
        /// <summary>
        /// 站点集合
        /// </summary>
        public IReadOnlyList<StationResultDto> Stations
        {
            get { return _stations; }
            set { SetProperty(ref _stations, value); }
        }

        /// <summary>
        /// 温湿度模型集合
        /// </summary>
        public ObservableCollection<NameValueSelectedModel<long>> THCollection { get; set; } = new ObservableCollection<NameValueSelectedModel<long>>();

        /// <summary>
        /// 趋势图数据集合
        /// </summary>
        public ObservableCollection<ISeries> Series { get; set; } = new ObservableCollection<ISeries>();

        /// <summary>
        /// 趋势图X轴集合
        /// </summary>
        public Axis[] XAxes { get; set; } = {
            new Axis
            {
                Labeler = value => value < 0 ? string.Empty : new DateTime((long)value).ToString("HH:mm:ss"),
                LabelsPaint = new SolidColorPaint(SKColors.White),
                UnitWidth = TimeSpan.FromMinutes(1).Ticks,
                MinStep = TimeSpan.FromMinutes(1).Ticks
            }
        };

        /// <summary>
        /// 趋势图Y轴集合
        /// </summary>
        public Axis[] YAxes { get; set; } = {
            new Axis
            {
                MinLimit = 0,
                MaxLimit = 100,
                LabelsPaint = new SolidColorPaint(SKColors.White)
            }
        };

        /// <summary>
        /// 提示文本对象
        /// </summary>
        public SolidColorPaint TooltipTextPaint { get; set; } = new SolidColorPaint
        {
            Color = SKColors.Black,
            SKTypeface = SKTypeface.FromFamilyName(FONT_FAMILY_NAME_MICROSOFT_YAHEI)
        };

        /// <summary>
        /// 铭文文本对象
        /// </summary>
        public SolidColorPaint LegendTextPaint { get; set; } = new SolidColorPaint
        {
            Color = SKColors.White,
            SKTypeface = SKTypeface.FromFamilyName(FONT_FAMILY_NAME_MICROSOFT_YAHEI)
        };

        public CentralMonitoringViewModel(RelayCommand selectCommand)
        {
            InitializeData(selectCommand);
            _timer = new Timer((state) =>
           {
               UpdateStations();
           }, null, 0, 1000);
        }

        private void InitializeData(RelayCommand selectCommand)
        {
            selectCommand.Executing += SelectCommand_Executing;
            IReadOnlyList<StationResultDto> stations = new List<StationResultDto>(DataCache.Stations);
            string format = Lang["站点"], tempName = Lang["温度"], humidtyName = Lang["湿度"];
            foreach (StationResultDto station in stations)
            {
                string title = string.Format(format, station.Identifier);
                station.DisplayName = title.Trim();
                NameValueSelectedModel<long> tempModel = new NameValueSelectedModel<long>($"{title}{tempName}", station.StationVariable.TempId, station.Identifier == 1) { SelectCommand = selectCommand };
                NameValueSelectedModel<long> humidityModel = new NameValueSelectedModel<long>($"{title}{humidtyName}", station.StationVariable.HumidityId, station.Identifier == 1) { SelectCommand = selectCommand };
                THCollection.Add(tempModel);
                THCollection.Add(humidityModel);
                if (station.Identifier == 1)
                {
                    AddSerie(tempModel);
                    AddSerie(humidityModel);
                }
            }
            Stations = stations;
        }

        private void SelectCommand_Executing(object parameter)
        {
            long id = (long)parameter;
            NameValueSelectedModel<long> thModel = THCollection.FirstOrDefault(th => th.Value == id);
            if (thModel == null)
            {
                return;
            }
            ISeries sv = Series.FirstOrDefault(s => id == (long)((LineSeries<ActualDataDto>)s).Tag);
            if (sv == null && thModel.IsSelected)
            {
                AddSerie(thModel);
            }
            else if (sv != null && !thModel.IsSelected)
            {
                Series.Remove(sv);
            }
        }

        private void AddSerie(NameValueSelectedModel<long> thModel)
        {
            Series.Add(new LineSeries<ActualDataDto>
            {
                Tag = thModel.Value,
                Name = thModel.Name,
                GeometrySize = 5,
                Values = DataCache.LongDateModelPairs[thModel.Value],
                Mapping = (actualData, point) =>
                {
                    point.SecondaryValue = actualData.CreationTime.Ticks;
                    point.PrimaryValue = actualData.Value;
                }
            });
        }

        private void UpdateStations()
        {
            if (!CommunicationCache.Connected)
            {
                return;
            }
            IReadOnlyList<StationResultDto> stations = new List<StationResultDto>(Stations);
            foreach (StationResultDto item in stations)
            {
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.StationAnomalyId))
                {
                    item.StationVariable.StationAnomalyValue = CommunicationCache.LongVariablePairs[item.StationVariable.StationAnomalyId].Value.ToBoolean();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.TempId))
                {
                    item.StationVariable.TempValue = CommunicationCache.LongVariablePairs[item.StationVariable.TempId].Value.ToDouble();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.HumidityId))
                {
                    item.StationVariable.HumidityValue = CommunicationCache.LongVariablePairs[item.StationVariable.HumidityId].Value.ToDouble();
                }
            }
            Stations = stations;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
            _timer.Dispose();
        }

        ~CentralMonitoringViewModel()
        {
            Dispose(false);
        }
    }
}
